<?php

use \think\exception\HttpResponseException;

/*--- 公用方法 ---*/
function pp($info)
{
    echo '<pre style="font-family: unset">';
    print_r($info);
    echo '</pre>';
}

// 统一成功返回json
function successReturn($data = [], $message = '操作成功!', $code = 0)
{
    $ret = [
        'msg' => config('code.' . $code),
        'code' => $code,
        'data' => $data,
    ];
    if ($message) {
        $ret['msg'] = $message;
    }
    return json($ret);
}

// 统一失败返回json
function errorReturn($message = '操作失败!', $data = [], $code = 1)
{
    $ret = [
        'msg' => config('code.' . $code),
        'code' => $code,
        'data' => $data,
    ];
    if ($message) {
        $ret['msg'] = $message;
    }
    return json($ret);
}

// 局部使用
function ajax($data = [], $code = 0, $message = '')
{
    $ret = [
        'msg' => $message,
        'code' => $code,
        'data' => $data,
    ];
    return json($ret);
}

function check_post($postArray)
{
    if (empty($postArray)) {
        throw new HttpResponseException(ajax($postArray, 2, "参数不能为空"));
    }
    foreach ($postArray as $value) {
        if (is_null($value) || $value === '') {
            throw new HttpResponseException(ajax($postArray, 2, "参数不能为空"));
        }
    }
    return true;
}

function has_value($param, $key)
{
    if (!isset($param[$key])) {
        return false;
    }
    if ($param[$key] === '') {
        return false;
    } else {
        return true;
    }
}

function myLog($cmd, $str, string $filename = 'common.log')
{
    if (is_string($str)) {
        $file = pathJoin(root_path(), "log", date('Y-m-d'), $filename);
        create_dir($file);
        $text = '[Time ' . date('Y-m-d H:i:s') . "]\ncmd:" . $cmd . "\n" . $str . "\n---END---" . "\n";
        if (false !== fopen($file, 'a+')) {
            file_put_contents($file, $text, FILE_APPEND);
        } else {
            echo '创建失败 file open error';
        }
    }
}

function pathJoin(...$path)
{
    foreach ($path as &$v) {
        $v = str_replace("\\", "/", $v);
    }
    $res = implode("/", $path);
    $res = str_replace("///", "/", $res);
    return str_replace("//", "/", $res);
}

function catchException($cmd, $e, string $filename = 'exception.log')
{
    myLog($cmd, var_export([
        'message' => $e->getMessage(),
        'file' => $e->getFile(),
        'line' => $e->getLine(),
    ], true), $filename);
}

function create_dir($file_path = '')
{
    $position = strripos($file_path, '/');
    $dirname = substr($file_path, 0, $position);
    if (!$dirname) {
        exit(json_encode(['msg' => 'invalid directory']));
    }
    if (!is_dir($dirname)) {
        @mkdir($dirname, 0755, true);
    }
}

function randomkeys($length)
{
    $returnStr = '';
    $pattern = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    for ($i = 0; $i < $length; $i++) {
        $returnStr .= $pattern [mt_rand(0, 61)];
    }
    return $returnStr;
}

function rand_name($length)
{
    $returnStr = '';
    $pattern = 'abcdefghijklmnopqrstuvwxyz';
    for ($i = 0; $i < $length; $i++) {
        $returnStr .= $pattern [mt_rand(0, 25)];
    }
    return $returnStr;
}

function gen_unique_number($letter = '')
{
    $time = explode(" ", microtime());
    $timeArr = explode('.', $time [0]);
    $mtime = array_pop($timeArr);
    $fulltime = $letter . $time[1] . $mtime;
    return $fulltime;
}

function create_unique_number($letter = '')
{
    $time = explode(" ", microtime());
    $timeArr = explode('.', $time [0]);
    $mtime = array_pop($timeArr);
    $fulltime = $letter . $time[1] . $mtime . mt_rand(100, 999);
    return $fulltime;
}

function get_filesize_str($kb)
{
    if ($kb >= 1024 * 1024) {
        return round($kb / 1024 / 1024, 2) . "GB";
    }
    if ($kb >= 1024) {
        return round($kb / 1024, 2) . "MB";
    }
    return $kb . "KB";
}

//接口上传图片
function upload_file($key, $allowType = [], $maxsize = 512, $editor = '')
{

    if ($_FILES[$key]["error"] > 0) {
        trigger_error("error: " . $_FILES[$key]["error"], E_USER_ERROR);
    }
    if ($_FILES[$key]["type"] == '') {
        trigger_error("文件存在中文名或超过2G ", E_USER_ERROR);
    }
    if ($allowType !== false && !in_array($_FILES[$key]["type"], $allowType)) {
        trigger_error("不支持的文件类型 " . $_FILES[$key]["type"], E_USER_ERROR);
    }
    if ($_FILES[$key]["size"] > $maxsize * 1024) {
        trigger_error("文件大小不超过 " . get_filesize_str($maxsize), E_USER_ERROR);
    }
//    $filename_array = explode('/', $_FILES[$key]['type']);
    $filename_array = explode('.', $_FILES[$key]['name']);
    $ext = array_pop($filename_array);
    if (in_array(strtolower($ext), ['php', 'js', 'asp', 'jsp', 'html', 'css', 'xml'])) {
        trigger_error("禁止的文件类型", E_USER_ERROR);
    }
    $path = 'tmp/';
    if ($editor === 'editor') {
        $path = 'upload/editor/';
    }
    is_dir($path) or mkdir($path, 0755, true);
    //转移临时文件
    $new_name = create_unique_number() . '.' . $ext;
    move_uploaded_file($_FILES[$key]["tmp_name"], $path . $new_name);
    return [
        'name' => $_FILES[$key]['name'],
        'url' => $path . $new_name,
    ];

}

function move_file_to_directory($from_obj, $to_path)
{
    $from_obj = pathJoin($from_obj);
    $to_path = pathJoin($to_path);
    $arr = explode('/', $from_obj);
    $to_obj = $to_path . end($arr);
    //如果一样不需要挪动
    if ($from_obj !== $to_obj) {
        create_dir($to_obj);
        rename($from_obj, $to_obj);
    }
    return [
        'code' => 0,
        'path' => $to_obj
    ];
}

function check_upload_file($file_url)
{
    if (!file_exists($file_url) || (!preg_match("/^tmp\//", $file_url) && !preg_match("/^upload\//", $file_url))) {
        return false;
    } else {
        return true;
    }
}

function conditionHandleZero($param, $field, $exp, &$where, $field_real = "")
{
    if (!$field_real) {
        $field_real = $field;
    }
    if (isset($param[$field]) && ($param[$field] || $param[$field] === 0 || $param[$field] === '0')) {
        if ($exp === 'like') {
            $where[] = [$field_real, $exp, "%{$param[$field]}%"];
        } else {
            $where[] = [$field_real, $exp, $param[$field]];
        }
    }
}

function conditionHandleIgnoreZero($param, $field, $exp, &$where, $field_real = "")
{
    if (!$field_real) {
        $field_real = $field;
    }
    if (isset($param[$field]) && ((is_string($param[$field]) && $param[$field] !== '') || (is_integer($param[$field]) && $param[$field] !== 0))) {
        if ($exp === 'like') {
            $where[] = [$field_real, $exp, "%{$param[$field]}%"];
        } else {
            $where[] = [$field_real, $exp, $param[$field]];
        }
    }
}

/*--- 项目专用 ---*/

// 验证统一社会信用代码
function validate_credit_code($code)
{
    $pattern = '/^[0-9ABCDEFGHJKLMNPQRTUWXY]{2}\d{6}[0-9ABCDEFGHJKLMNPQRTUWXY]{10}$/';
    if (preg_match($pattern, $code)) {
        $wi = array(1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28);
        $str = "0123456789ABCDEFGHJKLMNPQRTUWXY";
        $code = str_replace('I', '1', $code);
        $code = str_replace('O', '0', $code);
        $code = str_replace('Z', '2', $code);
        $sum = 0;
        for ($i = 0; $i < 17; $i++) {
            $sum += $wi[$i] * strpos($str, $code[$i]);
        }
        $c = 31 - $sum % 31;
        if ($c == 31) $c = 'Y';
        else $c = $str[$c];
        if ($c == $code[17]) {
            return true;
        }
    }
    return false;
}

// 验证密码, 包含大小写字母,数字, 特殊字符
function validate_password($password, $min_length = 8)
{
    $pattern = '/^(?![A-Za-z0-9]+$)(?![a-z0-9\\W]+$)(?![A-Za-z\\W]+$)(?![A-Z0-9\\W]+$)[a-zA-Z0-9\\W]{' . $min_length . ',32}$/';
    if (preg_match($pattern, $password)) {
        return true;
    }
    return false;
}

// 验证用户名, 包含大小写字母,数字
function validate_username($password, $min_length = 8)
{
    $pattern = '/^[a-zA-Z0-9]{6,32}$/';
    if (preg_match($pattern, $password)) {
        return true;
    }
    return false;
}

// 验证手机号
function validate_mobile($mobile)
{
    $pattern = '/^1[3-9]\d{9}$/';
    if (preg_match($pattern, $mobile)) {
        return true;
    }
    return false;
}

// 验证邮箱
function validate_email($email)
{
    $pattern = '/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/';
    if (preg_match($pattern, $email)) {
        return true;
    }
    return false;
}

// 传入参数验证
function validate_param($model_check, $param = [])
{
    $result = $model_check->check($param);
    if (!$result) {
        throw new HttpResponseException(ajax('', 2, $model_check->getError()));
    } else {
        return true;
    }
}

function validate_date($date, $datetime = false)
{
    $timestamp = strtotime($date);
    if ($datetime) {
        $ret = date('Y-m-d H:i:s', $timestamp);
    } else {
        $ret = date('Y-m-d', $timestamp);
    }
    return $date === $ret;
}

function editor_prefix_add($content)
{
    $editor_path = env('app.editor_path');
    return str_replace("src=\"upload/editor", "src=\"{$editor_path}upload/editor", $content);
}

function editor_prefix_remove($content)
{
    $editor_path = env('app.editor_path');
    return str_replace("src=\"{$editor_path}upload/editor", "src=\"upload/editor", $content);
}

// -n天前,+n天后
function date_dis_days($date, $n)
{
    return date('Y-m-d', strtotime("$n days", strtotime($date)));
}

// 获取某日期所在月的第一天和最后一天的日期
function date_head_tail_month($date)
{
    $head = date('Y-m-01', strtotime($date));
    $tail = date('Y-m-t', strtotime($date));
    return [
        $head, $tail
    ];
}

// 获取两个日期区间全部日期
function date_range($start_date, $end_date)
{
    $startDateTime = strtotime($start_date);
    $endDateTime = strtotime($end_date);
    $date_arr = [];
    while ($startDateTime <= $endDateTime) {
        $date_arr[] = date('Y-m-d', $startDateTime);
        $startDateTime = strtotime('+1 day', $startDateTime);
    }
    return $date_arr;
}


/*----- HTTP GET POST请求接口 -----*/

function curl_post_data($url, $curlPost, $headers = [],$userCert = false)
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    if ($userCert == true) {
        //设置证书
        //使用证书：cert 与 key 分别属于两个.pem文件
        curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
        curl_setopt($ch, CURLOPT_SSLCERT, config('wechat.cert_path'));
        curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
        curl_setopt($ch, CURLOPT_SSLKEY, config('wechat.key_path'));
    }
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
    curl_setopt($ch, 1, 2);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    $data = curl_exec($ch);
    curl_close($ch);
    return $data;
}

function curl_get_data($url, $data = [],$headers = [])
{
    $ch = curl_init();
    if ($data) {
        $querystring = http_build_query($data);
        $url = $url . '?' . $querystring;
    }
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);         // 执行后不直接打印出来
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // 跳过证书检查
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); // 不从证书中检查SSL加密算法是否存在
    $output = curl_exec($ch); //执行并获取HTML文档内容
    curl_close($ch); //释放curl句柄
    return $output;
}

//生成签名
function get_sign($param, $key)
{
    //去除数组中的空值
    $param = array_filter($param);
    //如果数组中有签名删除签名
    if (isset($param['sign'])) {
        unset($param['sign']);
    }
    //按照键名字典排序
    ksort($param);
    //生成URL格式的字符串
    $query = http_build_query($param) . "&key=" . $key;
    $query = urldecode($query);
    return strtoupper(md5($query));
}

function xml2array($xml)
{
    //禁止引用外部xml实体
    libxml_disable_entity_loader(true);
    $values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
    return $values;
}

//单层转
function array2xml($arr)
{
    if (!is_array($arr) || count($arr) <= 0) {
        return false;
    }
    $xml = "<xml>";
    foreach ($arr as $key => $val) {
        if (is_numeric($val)) {
            $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
        } else {
            $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
        }
    }
    $xml .= "</xml>";
    return $xml;
}

//递归转
function array2xml_r($data, $root = true)
{
    $str = "";
    if ($root) $str .= "<xml>";
    foreach ($data as $key => $val) {
        //去掉key中的下标[]
        $key = preg_replace('/\[\d*\]/', '', $key);
        if (is_array($val)) {
            $child = arr2xml($val, false);
            $str .= "<$key>$child</$key>";
        } else {
            $str .= "<$key><![CDATA[$val]]></$key>";
        }
    }
    if ($root) $str .= "</xml>";
    return $str;
}

function json_2_array($json)
{
    $arr = json_decode($json, true);
    if (!$json || $arr === false) {
        return [];
    }
    return array_filter($arr);
}
